﻿
using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using System.Xml;
using ComponentFactory.Krypton.Toolkit;
using Microsoft.Practices.ServiceLocation;
using Castle.Windsor;
using log4net;
using OAuth.Net.Consumer;
using OAuth.Net.Components;
using EndPoint = OAuth.Net.Consumer.EndPoint;
using System.Collections.Specialized;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
using OAuth.Net.Common;
using Newtonsoft.Json.Linq;
using System.Web;
using System.Diagnostics;

namespace OAuthClient
{
    /// <summary>
    ///     
    /// </summary>
    public partial class OAuthForm : KryptonForm
    {
        /// <summary>
        /// 
        /// </summary>
        private static readonly ILog _log = LogManager.GetLogger(typeof(OAuthForm));

        /// <summary>
        /// 
        /// </summary>
        readonly Dictionary<string, LogViewItem> _logRequests = new Dictionary<string, LogViewItem>();

        /// <summary>
        /// 
        /// </summary>
        readonly Dictionary<string, LogViewItem> _logResponses = new Dictionary<string, LogViewItem>();

        /// <summary>
        ///     
        /// </summary>
        ServiceConfigs _serviceConfigs;

        /// <summary>
        /// 
        /// </summary>
        IWindsorContainer _container;

        /// <summary>
        ///     
        /// </summary>
        public OAuthForm()
        {
            InitializeComponent();
            Text = "Not logged in";
            InitializeLogView();
            InitializeResultsView();
            InitializeApiConfigs();
        }

        /// <summary>
        /// 
        /// </summary>
        private void InitializeApiConfigs()
        {
            _container = ServiceLocator.Current.GetService(typeof(IWindsorContainer)) as IWindsorContainer;
            _serviceConfigs = _container.Resolve<ServiceConfigs>();
            _usernameTextBox.Text = _serviceConfigs.XAuthUsername;
            _passwordTextBox.Text = _serviceConfigs.XAuthPassword;
            _consumerKeyTextBox.Text = _serviceConfigs.OAuthConsumerKey;
            _consumerSecretTextBox.Text = _serviceConfigs.OAuthConsumerSecret;
            _testServiceUrlTextBox.Text = _serviceConfigs.DefaultTestServiceUrl;
        }

        /// <summary>
        /// 
        /// </summary>
        private void InitializeResultsView()
        {
            var dt = new DataTable();
            dt.Columns.Add(new DataColumn("key"));
            dt.Columns.Add(new DataColumn("order"));
            dt.Columns.Add(new DataColumn("content"));
            _resultsGridView.AutoGenerateColumns = false;
            _resultsGridView.DataSource = dt;
        }

        /// <summary>
        /// 
        /// </summary>
        private void InitializeLogView()
        {
            var dt = new DataTable();
            dt.Columns.Add(new DataColumn("key"));
            dt.Columns.Add(new DataColumn("order"));
            dt.Columns.Add(new DataColumn("content"));
            _logGridView.AutoGenerateColumns = false;
            _logGridView.DataSource = dt;
        }

        #region [ Web Method ]

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnWebLoginButtonClick(object sender, EventArgs e)
        {
            if (string.Compare(_webLoginButton.Text, "Not continue", false) == 0)
            {
                _webLoginButton.Text = "Login";
                _webContinueButton.Enabled = false;
                _verifierButton.Enabled = false;
                _pinTextBox.Enabled = false;
                _pinTextBox.Text = string.Empty;
                return;
            }

            try
            {
                var oauthService = OAuthService.Create(
                    new EndPoint(_serviceConfigs.OAuthRequestTokenUrl),
                    new Uri(_serviceConfigs.OAuthAuthorizeUrl),
                    new EndPoint(_serviceConfigs.OAuthAccessTokenUrl),
                    false,
                    string.Empty,
                    "HMAC-SHA1",
                    "1.0",
                    new OAuthConsumer(_consumerKeyTextBox.Text, _consumerSecretTextBox.Text)
                );

                // create authorize request
                var oauthRequest = OAuthRequest.Create(
                    new EndPoint(_serviceConfigs.OAuthAuthorizeUrl, "GET"),
                    oauthService);

                oauthRequest.BeforeSendHttpWebRequest += (s, args) => { InsertRequestLog(args); };

                // parse request token
                oauthRequest.RequestTokenParseHandler = (oauth, args) =>
                {
                    args.IsHandled = true;
                    args.OAuthParameters = ParseRequestToken(args.OAuthResource);
                };

                oauthRequest.GetRequestToken();
                if (oauthRequest.RequestToken == null)
                {
                    KryptonMessageBox.Show("Request token was not received.");
                    return;
                }

                _webLoginButton.Text = "Not continue";
                _webContinueButton.Enabled = true;
                _verifierButton.Enabled = true;
                _pinTextBox.Enabled = true;

                // the following line will load the URL in the users default browser.
                var authorizeUrl = string.Format("{0}?{1}={2}", oauthRequest.Service.AuthorizationUrl,
                    Constants.TokenParameter, oauthRequest.RequestToken.Token);
                Process.Start(authorizeUrl);

                _tokenTextBox.Text = oauthRequest.RequestToken != null ?
                    oauthRequest.RequestToken.Token : string.Empty;
                _tokenSecretTextBox.Text = oauthRequest.RequestToken != null ?
                    oauthRequest.RequestToken.Secret : string.Empty;

                _tokenTypeRequestRadioButton.Checked = oauthRequest.RequestToken != null &&
                    !string.IsNullOrEmpty(oauthRequest.RequestToken.Secret);
                _tokenTypeAccessRadioButton.Checked = false;
            }
            catch (Exception ex)
            {
                KryptonMessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnVerifierButtonClick(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_tokenTextBox.Text))
            {
                KryptonMessageBox.Show("Request token was not received.");
            }

            // the following line will load the URL in the users default browser.
            var authorizeUrl = string.Format("{0}?{1}={2}", _serviceConfigs.OAuthAuthorizeUrl,
                Constants.TokenParameter, _tokenTextBox.Text);
            Process.Start(authorizeUrl);
        }

        private void OnContinueButtonClick(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_pinTextBox.Text))
            {
                KryptonMessageBox.Show("Enter the PIN to continue authorization process.");
                return;
            }

            try
            {
                var oauthService = OAuthService.Create(
                     new EndPoint(_serviceConfigs.OAuthRequestTokenUrl),
                     new Uri(_serviceConfigs.OAuthAuthorizeUrl),
                     new EndPoint(_serviceConfigs.OAuthAccessTokenUrl),
                     false,
                     string.Empty,
                     "HMAC-SHA1",
                     "1.0",
                     new OAuthConsumer(_consumerKeyTextBox.Text, _consumerSecretTextBox.Text)
                 );

                // create authorize request
                var requestToken = new OAuthToken(TokenType.Request, _tokenTextBox.Text,
                    _tokenSecretTextBox.Text, _consumerKeyTextBox.Text);
                var oauthRequest = OAuthRequest.Create(
                    new EndPoint(_serviceConfigs.OAuthAccessTokenUrl, "GET"),
                    oauthService, null, requestToken, _pinTextBox.Text, null);

                oauthRequest.BeforeSendHttpWebRequest += (s, args) => { InsertRequestLog(args); };

                // parse access token
                oauthRequest.AccessTokenParseHandler = (oauth, args) =>
                {
                    args.IsHandled = true;
                    args.OAuthParameters = ParseAccessToken(args.OAuthResource);
                };

                oauthRequest.GetAccessToken();

                if (oauthRequest.AccessToken != null &&
                    !string.IsNullOrEmpty(oauthRequest.AccessToken.Secret))
                {
                    _tokenTextBox.Text = oauthRequest.AccessToken != null ?
                        oauthRequest.AccessToken.Token : string.Empty;
                    _tokenSecretTextBox.Text = oauthRequest.AccessToken != null ?
                        oauthRequest.AccessToken.Secret : string.Empty;

                    _tokenTypeAccessRadioButton.Checked = true;
                    _tokenTypeRequestRadioButton.Checked = false;

                    _webLoginButton.Text = "Login";
                    _webContinueButton.Enabled = false;
                    _verifierButton.Enabled = false;
                    _pinTextBox.Enabled = false;
                    _pinTextBox.Text = string.Empty;
                }
            }
            catch (Exception ex)
            {
                KryptonMessageBox.Show(ex.Message);
            }
        }

        #endregion

        #region [ Direct Method ]

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnXAuthLoginButtonClick(object sender, EventArgs e)
        {
            try
            {
                var oauthService = OAuthService.Create(
                    new EndPoint(_serviceConfigs.OAuthRequestTokenUrl),
                    new Uri(_serviceConfigs.OAuthAuthorizeUrl),
                    new EndPoint(_serviceConfigs.OAuthAccessTokenUrl),
                    false,
                    string.Empty,
                    "HMAC-SHA1",
                    "1.0",
                    new OAuthConsumer(_consumerKeyTextBox.Text, _consumerSecretTextBox.Text)
                );

                // consume math service
                var oauthRequest = OAuthRequest.Create(
                    new EndPoint(_serviceConfigs.XAuthLoginUrl,
                        _getRadioButton.Checked ? "GET" : "POST"),
                    oauthService);
                oauthRequest.BeforeSendHttpWebRequest += (s, args) => { InsertRequestLog(args); };

                var passwordHash = string.Empty;
                using (var hash = new SHA1Managed())
                {
                    byte[] passwordBytes = Encoding.UTF8.GetBytes(_passwordTextBox.Text);
                    byte[] hashBytes = hash.ComputeHash(passwordBytes);

                    Array.ForEach(hashBytes, b =>
                    {
                        var hexaByte = b.ToString("X").ToLower();
                        // lowercase for compatibility on case-sensitive systems
                        passwordHash += (hexaByte.Length == 1 ? "0" : "") + hexaByte;
                    });
                }

                var requestParameters = new NameValueCollection()
                {
                    { "x_auth_mode", "client_auth" },
                    { "x_auth_username", _usernameTextBox.Text },
                    { "x_auth_password", passwordHash },
                };

                if (_xmlRadioButton.Checked)
                {
                    requestParameters.Add("format", "xml");
                }
                else if (_jsonRadioButton.Checked)
                {
                    requestParameters.Add("format", "json");
                }
                else if (_plainTextRadioButton.Checked)
                {
                    requestParameters.Add("format", "plain-text");
                }

                var oauthResponse = oauthRequest.GetPublicResource(requestParameters);
                var oauthParameters = ParseOAuthToken(oauthResponse.ProtectedResource, true);
                if (!string.IsNullOrEmpty(oauthParameters.TokenSecret))
                {
                    _tokenTypeAccessRadioButton.Checked = true;
                    _tokenTypeRequestRadioButton.Checked = false;
                }
            }
            catch (Exception ex)
            {
                KryptonMessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="oAuthResource"></param>
        /// <returns></returns>
        private OAuthParameters ParseAccessToken(OAuthResource oauthResource)
        {
            return ParseOAuthToken(oauthResource, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="oAuthResource"></param>
        /// <returns></returns>
        private OAuthParameters ParseRequestToken(OAuthResource oauthResource)
        {
            return ParseOAuthToken(oauthResource, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reponse"></param>
        private OAuthParameters ParseOAuthToken(OAuthResource oauthResource)
        {
            return ParseOAuthToken(oauthResource, false);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reponse"></param>
        private OAuthParameters ParseOAuthToken(OAuthResource oauthResource, bool logResponse)
        {
            if (oauthResource == null)
            {
                return null;
            }

            var bodyParams = new NameValueCollection();
            using (var ms = new MemoryStream())
            {
                var responseStream = oauthResource.GetResponseStream();
                byte[] buffer = new byte[32768];

                int bytesRead;
                while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, bytesRead);
                }

                var bodyEncoding = Encoding.ASCII;
                if (!string.IsNullOrEmpty(oauthResource.ContentEncoding))
                {
                    bodyEncoding = Encoding.GetEncoding(oauthResource.ContentEncoding);
                }

                string responseBody = bodyEncoding.GetString(ms.ToArray());
                if (logResponse)
                {
                    InsertResponseLog(responseBody, oauthResource.Headers);
                }

                if (string.Compare(oauthResource.ContentType, "text/html", false) == 0)
                {
                    bodyParams = ParseOAuthToken(responseBody);
                }
                else if (string.Compare(oauthResource.ContentType, "text/xml", false) == 0)
                {
                    var doc = new XmlDocument();
                    doc.LoadXml(responseBody);
                    bodyParams = ParseOAuthToken(doc);
                }
                else if (string.Compare(oauthResource.ContentType, "application/json", false) == 0)
                {
                    var json = JObject.Parse(responseBody);
                    bodyParams = ParseOAuthToken(json);
                }

                if (bodyParams.AllKeys.Contains(Constants.TokenParameter))
                {
                    _tokenTextBox.Text = bodyParams[Constants.TokenParameter];
                }

                if (bodyParams.AllKeys.Contains(Constants.TokenSecretParameter))
                {
                    _tokenSecretTextBox.Text = bodyParams[Constants.TokenSecretParameter];
                }

                // reset the stream
                responseStream.Position = 0;
            }

            return OAuthParameters.DoParse(null,
                oauthResource.Headers[Constants.WwwAuthenticateHeaderParameter],
                bodyParams, null, OAuthParameterSources.ConsumerDefault, false);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="responseBody"></param>
        private static NameValueCollection ParseOAuthToken(string responseBody)
        {
            var bodyParams = new NameValueCollection();
            var nameValuePairs = responseBody.Split(new char[] { '&' },
                StringSplitOptions.RemoveEmptyEntries);

            Array.ForEach(nameValuePairs, nameValuePair =>
            {
                var nameValuePairParts = nameValuePair.Split(new char[] { '=' },
                    StringSplitOptions.RemoveEmptyEntries);
                if (nameValuePairParts.Length == 2)
                {
                    bodyParams.Add(HttpUtility.UrlDecode(nameValuePairParts[0]),
                        HttpUtility.UrlDecode(nameValuePairParts[1]));
                }
                else if (nameValuePairParts.Length == 1)
                {
                    bodyParams.Add(HttpUtility.UrlDecode(nameValuePairParts[0]),
                        string.Empty);
                }
            });

            return bodyParams;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="doc"></param>
        /// <returns></returns>
        private static NameValueCollection ParseOAuthToken(XmlDocument doc)
        {
            var bodyParams = new NameValueCollection();
            var resultNode = doc.SelectSingleNode("//rsp/result");

            foreach (var attr in resultNode.Attributes)     // if use attribute
            {
                bodyParams.Add(HttpUtility.UrlDecode(((XmlAttribute)attr).LocalName),
                    HttpUtility.UrlDecode(((XmlAttribute)attr).Value));
            }

            foreach (var node in resultNode.ChildNodes)
            {
                bodyParams.Add(HttpUtility.UrlDecode(((XmlNode)node).LocalName),
                    HttpUtility.UrlDecode(((XmlNode)node).InnerText));
            }

            return bodyParams;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        private static NameValueCollection ParseOAuthToken(JObject json)
        {
            var bodyParams = new NameValueCollection();
            var keys = json.Properties().Select(p => p.Name).ToList();
            keys.ForEach(key => bodyParams.Add(key,
                HttpUtility.UrlDecode(json.Property(key).Value.ToString())));

            return bodyParams;
        }

        #endregion

        /// <summary>
        ///     
        /// </summary>
        private void OnAddArgButtonClick(object sender, EventArgs e)
        {

            if (string.IsNullOrEmpty(_argNameTextBox.Text))
            {
                return;
            }
            _argsDataGridView.Rows.Add(new object[] { _argNameTextBox.Text, _argValueTextBox.Text });
        }

        /// <summary>
        ///     
        /// </summary>
        private void OnRemoveLastArgButtonClick(object sender, EventArgs e)
        {

            if (_argsDataGridView.Rows.Count > 0)
            {
                _argsDataGridView.Rows.RemoveAt(_argsDataGridView.Rows.Count - 1);
            }
        }

        /// <summary>
        ///     
        /// </summary>
        private void OnClearAllArgsButtonClick(object sender, EventArgs e)
        {
            _argsDataGridView.Rows.Clear();
        }

        /// <summary>
        ///     
        /// </summary>
        private void OnActionButtonClick(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_testServiceUrlTextBox.Text))
            {
                return;
            }

            try
            {
                var oauthConsumer = new OAuthConsumer(_consumerKeyTextBox.Text,
                    _consumerSecretTextBox.Text);
                var oauthService = OAuthService.Create(
                    new EndPoint(_serviceConfigs.OAuthRequestTokenUrl),
                    new Uri(_serviceConfigs.OAuthAuthorizeUrl),
                    new EndPoint(_serviceConfigs.OAuthAccessTokenUrl),
                    false,
                    string.Empty,
                    "HMAC-SHA1",
                    "1.0",
                    oauthConsumer
                );

                var isProtectedResource = _protectedResourceCheckBox.Checked;

                OAuthRequest oauthRequest;
                if (isProtectedResource)
                {
                    var requestToken = new EmptyToken(_consumerKeyTextBox.Text, TokenType.Request);
                    var accessToken = new OAuthToken(TokenType.Access, _tokenTextBox.Text,
                        _tokenSecretTextBox.Text, oauthConsumer);

                    oauthRequest = OAuthRequest.Create(
                        new EndPoint(_testServiceUrlTextBox.Text,
                            _getRadioButton.Checked ? "GET" : "POST"),
                        oauthService, requestToken, accessToken);
                }
                else
                {
                    oauthRequest = OAuthRequest.Create(
                        new EndPoint(_testServiceUrlTextBox.Text,
                            _getRadioButton.Checked ? "GET" : "POST"),
                        oauthService);
                }

                oauthRequest.BeforeSendHttpWebRequest += (s, args) => { InsertRequestLog(args); };

                var requestParameters = new NameValueCollection();
                foreach (var row in _argsDataGridView.Rows)
                {
                    requestParameters.Add(((DataGridViewRow)row).Cells[0].Value.ToString(),
                        ((DataGridViewRow)row).Cells[1].Value.ToString());
                }

                if (_xmlRadioButton.Checked)
                {
                    requestParameters.Add("format", "xml");
                }
                else if (_jsonRadioButton.Checked)
                {
                    requestParameters.Add("format", "json");
                }
                else if (_plainTextRadioButton.Checked)
                {
                    requestParameters.Add("format", "plain-text");
                }

                var oauthResponse = isProtectedResource ?
                    oauthRequest.GetProtectedResource(requestParameters) :
                    oauthRequest.GetPublicResource(requestParameters);
                ReadOAuthResponse(oauthResponse);
            }
            catch (Exception ex)
            {
                KryptonMessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="response"></param>
        private void ReadOAuthResponse(OAuthResponse oauthResponse)
        {
            var oauthResource = oauthResponse.HasProtectedResource ?
                oauthResponse.ProtectedResource : null;

            if (oauthResource == null)
            {
                InsertResponseLog("-- EMPTY --", null);
                return;
            }

            using (var ms = new MemoryStream())
            {
                var responseStream = oauthResource.GetResponseStream();
                byte[] buffer = new byte[32768];

                int bytesRead;
                while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, bytesRead);
                }

                var bodyEncoding = Encoding.ASCII;
                if (!string.IsNullOrEmpty(oauthResource.ContentEncoding))
                {
                    bodyEncoding = Encoding.GetEncoding(oauthResource.ContentEncoding);
                }

                string responseBody = bodyEncoding.GetString(ms.ToArray());

                InsertResponseLog(responseBody, oauthResource.Headers);
            }
        }

        /// <summary>
        ///     
        /// </summary>
        private void OnResultGridViewCellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            var dr = (_resultsGridView.Rows[e.RowIndex]
                .DataBoundItem as DataRowView).Row;
            var key = dr["key"].ToString();
            var response = _logResponses[key];

            string content = response.Message;

            try
            {
                var doc = new XmlDocument();

                doc.LoadXml(content);
                using (var form = new XmlForm(response))
                {
                    form.ShowDialog(this);
                }
            }
            catch
            {
                using (var form = new TextForm(content))
                {
                    form.ShowDialog(this);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnLogGridViewCellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            var dr = (_logGridView.Rows[e.RowIndex]
                .DataBoundItem as DataRowView).Row;
            var key = dr["key"].ToString();
            var request = _logRequests[key];
            using (var form = new TextForm(request))
            {
                form.ShowDialog(this);
            }
        }

        /// <summary>
        ///     
        /// </summary>
        /// <param name="sender" type="object">
        ///     
        /// </param>
        /// <param name="e" type="System.EventArgs">
        ///     
        /// </param>
        private void OnClearLogButtonClick(object sender, EventArgs e)
        {
            _logRequests.Clear();
            (_logGridView.DataSource as DataTable).Rows.Clear();
            _logResponses.Clear();
            (_resultsGridView.DataSource as DataTable).Rows.Clear();
        }

        /// <summary>
        ///     
        /// </summary>
        private void SanitizeInput()
        {
            _consumerKeyTextBox.Text = _consumerKeyTextBox.Text.Trim();
            _consumerSecretTextBox.Text = _consumerSecretTextBox.Text.Trim();
            _tokenTextBox.Text = _tokenTextBox.Text.Trim();
            _usernameTextBox.Text = _usernameTextBox.Text.Trim();
            _passwordTextBox.Text = _passwordTextBox.Text.Trim();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="responseBody"></param>
        /// <param name="headers"></param>
        private void InsertResponseLog(string responseBody, NameValueCollection headers)
        {
            var dt = _resultsGridView.DataSource as DataTable;
            var dr = dt.NewRow();

            var key = Guid.NewGuid().ToString();
            var order = _resultsGridView.Rows.Count + 1;
            dr["order"] = order;
            dr["key"] = key;

            dr["content"] = responseBody;
            dt.Rows.InsertAt(dr, 0);

            _logResponses.Add(key, new LogViewItem
            {
                Key = key,
                Order = order,
                Headers = headers,
                Message = responseBody,
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void InsertRequestLog(PreSendHttpWebRequestEventArgs e)
        {
            var dt = _logGridView.DataSource as DataTable;
            var dr = (_logGridView.DataSource as DataTable).NewRow();

            var order = _logGridView.Rows.Count + 1;
            var key = Guid.NewGuid().ToString();
            var url = string.Format("{0} {1}", e.Method, e.RequestUri.AbsoluteUri);
            dr["key"] = key;
            dr["order"] = order;
            dr["content"] = url;
            dt.Rows.InsertAt(dr, 0);

            _logRequests.Add(key, new LogViewItem
            {
                Key = key,
                Order = order,
                Headers = e.Headers,
                Message = url,
                Extra = e.BodyContent,
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnServicesDropButtonClick(object sender, EventArgs e)
        {

        }
    }
}
